﻿using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using System.Data;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Himp.TaskScheduling.Hangfire
{
    /// <summary>
    /// 制样记录worker
    /// </summary>
    public class SamplePreparationRecWorker : IHostedService
    {
        #region SQL

        public const string GET_SAMPLE_PREPARATION_REC_SQL = @"
            SELECT [ID]
                  ,[MachineCode]
                  ,[SampleID]
                  ,[PackCode]
                  ,[ZYWeight]
                  ,[ZYType]
                  ,[SampleType]
                  ,[Size]
                  ,[Water]
                  ,[StartTime]
                  ,[EndTime]
                  ,[SamepleWeight] as SampleWeight
                  ,[UserName]
            FROM [dbo].[ZY_RECORD_TB]
            WHERE [DataStatus]='0'
            ";

        public const string EXIST_FLAG_SQL = @"
            SELECT CASE WHEN 
            EXISTS (SELECT 1 FROM [dbo].[HY_SamplePreparationRec] WHERE SampleID = @SampleID AND PackCode =@PackCode) 
            THEN 1 
            ELSE 0 
            END";

        public const string INSERT_SAMPLE_PREPARATION = @"
            INSERT INTO
            [dbo].[HY_SamplePreparationRec]
            (
            [MachineCode]
            ,[SampleID]
            ,[PackCode]
            ,[ZYWeight]
            ,[ZYType]
            ,[SampleType]
            ,[Size]
            ,[Water]
            ,[StartTime]
            ,[EndTime]
            ,[SampleWeight]
            ,[UserName]
            )
            VALUES
            (
            @MachineCode
            ,@SampleID
            ,@PackCode
            ,@ZYWeight
            ,@ZYType
            ,@SampleType
            ,@Size
            ,@Water
            ,@StartTime
            ,@EndTime
            ,@SampleWeight
            ,@UserName
            )
            ";

        public const string INSERT_STANDARD_TEST_TASK_SQL = @"
            INSERT INTO
            [TaskScheduling].[TS_StandardTestTasks]
            (
            SampleCode,
            TestCode,
            BottomCode,
            Sampletype,
            TaskType,
            SampeWay,
            TestCnt,
            TaskAssgnTime,
            LastOperTime,
            ExecStas
            )
            VALUES
            (
            @SampleCode,
            @TestCode,
            @BottomCode,
            @Sampletype,
            @TaskType,
            @SampeWay,
            @TestCnt,
            GETDATE(),
            GETDATE(),
            @ExecStas
            )
            ";

        public const string UPDATE_SAMPLE_PREPARATION_STAS_SQL = @"
            UPDATE
            [dbo].[ZY_RECORD_TB]
            SET
            DataStatus='1'
            WHERE
            ID=@ID";

        #endregion

        #region 字段

        private readonly ConnectionStringOption _connectionStrings;
        private ILogger<SamplePreparationRecWorker> _logger;

        #endregion

        #region 方法

        public SamplePreparationRecWorker(ILogger<SamplePreparationRecWorker> logger
            ,IOptions<ConnectionStringOption> connectionStrings)
        {
            _logger = logger;
            _connectionStrings = connectionStrings.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("--------制样结果To标准化验任务开始启动--------");
            // 从源数据库读取数据
            IEnumerable<SamplePreparationRec> data = GetSamplePreparationRec();
            await QrCodeToSampleCode(data);
            _logger.LogInformation("--------制样结果To标准化验任务完成--------");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IEnumerable<SamplePreparationRec> GetSamplePreparationRec()
        {
            try
            {
                using (IDbConnection connection = new SqlConnection(_connectionStrings.KaiY_Preparation))
                {
                    connection.Open();
                    // 读取数据
                    var samplePreparationRecList = connection.Query<SamplePreparationRec>(GET_SAMPLE_PREPARATION_REC_SQL);

                    return samplePreparationRecList;
                }
            }
            catch (Exception e)
            {
                _logger.LogError(exception: e, "异常:GetSamplePreparationRec");
            }

            return new List<SamplePreparationRec>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task QrCodeToSampleCode(IEnumerable<SamplePreparationRec> datas)
        {
            try
            {
                using (IDbConnection connection = new SqlConnection(_connectionStrings.RL_Web))
                {
                    connection.Open();

                    foreach (var data in datas)
                    {
                        // 检查 ID 是否已存在
                        bool exists = await connection.ExecuteScalarAsync<bool>(EXIST_FLAG_SQL,
                            new { data.SampleID, data.PackCode });

                        if (!exists)
                        {
                            await UpdateSamplePreparationStas(data);
                            var codeStas = await connection.ExecuteAsync(INSERT_SAMPLE_PREPARATION, data);
                            _logger.LogInformation($"制样结果同步任务:{data.ID}:{codeStas}");
                        }
                        else
                        {
                            _logger.LogInformation($"制样结果同步任务:{data.ID}:已添加");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(exception: e, "异常:QrCodeToSampleCode");
            }
        }

        /// <summary>
        /// 生成标准化制样任务
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task UpdateSamplePreparationStas(SamplePreparationRec data)
        {
            using (IDbConnection connection = new SqlConnection(_connectionStrings.RL_Web))
            {
                CodeConversionManager codeConversionManager = new CodeConversionManager(_connectionStrings);
                var codeConversionResult = codeConversionManager.GenerateTestingNo(data.SampleID, data.UserName);
                
                if (!codeConversionResult.Item1)
                {
                    _logger.LogError("生成化验码异常");
                    return;
                }

                string randomCode = codeConversionResult.Item2;

                if (data.SampleType == 1)
                {
                    var intStas = await connection.ExecuteAsync(INSERT_STANDARD_TEST_TASK_SQL,
                        new
                        {
                            SampleCode = data.SampleID,
                            TestCode =  randomCode,
                            BottomCode = data.PackCode,
                            Sampletype = "61",
                            TaskType = 0,
                            SampeWay = "自动",
                            TestCnt = 2,
                            ExecStas = "未就绪"
                        });
                    _logger.LogInformation($"生成标准化验任务:{data.PackCode}:{intStas}");
                }
                else if(data.SampleType == 4)
                {
                    var intStas = await connection.ExecuteAsync(INSERT_STANDARD_TEST_TASK_SQL,
                        new
                        {
                            SampleCode = data.SampleID,
                            TestCode = randomCode,
                            BottomCode = data.PackCode,
                            Sampletype = "21",
                            TaskType = 0,
                            SampeWay = "自动",
                            TestCnt = 2,
                            ExecStas = "未就绪"
                        });
                    _logger.LogInformation($"生成标准化验任务:{data.PackCode}:{intStas}");
                }
            }

            using (IDbConnection connection = new SqlConnection(_connectionStrings.KaiY_Preparation))
            {
                connection.Open();
                var codeStas = await connection.ExecuteAsync(UPDATE_SAMPLE_PREPARATION_STAS_SQL,
                    new { ID = data.ID });
                _logger.LogInformation($"更新制样结果状态任务:{data.ID}:{codeStas}");
            }
        }

        #endregion
    }
}
